package org.batatasframework.values;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.util.ClassUtils;

import cn.bonoon.kernel.util.StringHelper;

public abstract class AbstractStringValueGetter implements ValueGetter{

	private final static DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
	private static ObjectMapper mapper;

	protected abstract String internalValue();

	@Override
	public Date getDate(Object arg) {
		try {
			String value = internalValue();
			
			if(arg instanceof DateFormat){
				return ((DateFormat)arg).parse(value);
			}
			
			if(arg instanceof String){
				return new SimpleDateFormat((String)arg).parse(value);
			}
			
			return DATE_FORMAT.parse(value);
			
		} catch (ParseException e) {
			return null;
		}
	}

	/** 参考：{@link #toEnum(Class, Enum)} */
	@Override
	public final <E extends Enum<E>> E toEnum(Class<E> clazz){
		String value = internalValue();
		if(StringHelper.isNotEmpty(value)){
			try{
				return Enum.valueOf(clazz, value.toUpperCase());
			}catch (Exception e) {
				//nothing to do and try next
			}
		}
		return null;
	}
	
	@Override
	public final Class<?> getClassType() {
		try{
			return ClassUtils.forName(internalValue(), getClass().getClassLoader());
		}catch (Exception e) {
			return null;
		}
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public List<String> asList(){
		return StringHelper.toList(internalValue());
	}
	
	@Override
	public String toString() {
		return internalValue();
	}
	
	@Override
	public String getString(){
		return internalValue();
	}
	
	@Override
	public Integer getInteger(){
		return StringHelper.toInteger(internalValue());
	}
	
	@Override
	public Long getLong(){
		return StringHelper.toLong(internalValue());
	}
	
	@Override
	public Boolean getBoolean(){
		return StringHelper.toBoolean(internalValue());
	}
	
	@Override
	public Double getDouble() {
		return StringHelper.toDouble(internalValue());
	}
	
	@Override
	public <T> T getObject(Class<T> clazz){
		if(null != clazz){
			if(null == mapper) mapper = new ObjectMapper();
			try {
				return mapper.readValue(internalValue(), clazz);
			} catch (Exception e) {
				//nothing to do
			}
		}else if(String.class.isAssignableFrom(clazz)){
			return clazz.cast(internalValue());
		}
		return null;
	}
	
	@Override
	public boolean is(Object target) {
		return target.equals(internalValue());
	}
}
